package com.back.demo.controller;

import com.back.demo.common.CommonResult;
import com.back.demo.common.Permission;
import com.back.demo.controller.myVO.basicVO.*;
import com.back.demo.exception.GlobalException;
import com.back.demo.service.BasicService;
import com.back.demo.util.JwtTokenUtil;
import com.back.demo.common.User;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import io.jsonwebtoken.ExpiredJwtException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;

import java.util.ArrayList;

import static com.back.demo.controller.myVO.errorBeanEnum.BasicResponseBeanEnum.*;

@Api(tags = "基础功能")
@RestController
@RequestMapping("/server/basic")
@Slf4j
public class BasicController {

    @Autowired
    private BasicService basicService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private DefaultKaptcha defaultKaptcha;

    @ApiOperation("验证码接口")
    @GetMapping("/get-captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) {

        // 生成验证码文本
        String captchaText = defaultKaptcha.createText();

        // 将验证码文本存储在会话中，以供后续验证
        request.getSession().setAttribute("captcha", captchaText);

        // 生成验证码图片
        BufferedImage captchaImage = defaultKaptcha.createImage(captchaText);

        // 将验证码图片写入响应
        response.setContentType("image/png");
        try (OutputStream outputStream = response.getOutputStream()) {
            ImageIO.write(captchaImage, "png", outputStream);
            outputStream.flush();
        } catch (IOException e) {
            log.error("生成验证码时出现异常");
        }
    }

    @ApiOperation("登录接口")
    @PostMapping("/login")
    public CommonResult<?> login(HttpServletRequest request, @RequestBody LoginVO loginRequestVO) {

        // 从 session 中解析出验证码
        String storedCaptcha = (String) request.getSession().getAttribute("captcha");

        // 无论验证码是正确还是错误，都要清除验证码
        request.getSession().removeAttribute("captcha");

        // 验证码错误，返回错误消息
        if (!loginRequestVO.getCaptcha().equalsIgnoreCase(storedCaptcha)) {
            return CommonResult.error(CAPTCHA_ERROR);
        }

        // 验证码正确，执行登录逻辑
        try {
            // 查询用户
            String username = loginRequestVO.getUsername();
            User user = basicService.findUserByUsername(username);

            // user不可能为null了，因为如果为null会直接抛出 GlobalException 异常
            if (!loginRequestVO.getPassword().equals(user.getPassword())) {
                return CommonResult.error(LOGIN_ERROR);
            }

            // 生成访问令牌和刷新令牌
            String accessToken = jwtTokenUtil.generateAccessToken(username);
            String refreshToken = jwtTokenUtil.generateRefreshToken(username);

            // 响应前端
            LoginResponseVO loginResponseVO = new LoginResponseVO(accessToken, refreshToken);
            return CommonResult.success(loginResponseVO);
        } catch (GlobalException e) {
            // 用户不存在
            return CommonResult.error(LOGIN_ERROR);
        }
    }

    @GetMapping("/permission")
    public CommonResult<?> getPermission(@RequestHeader("Authorization") String authHeader) {
        // 解析Authorization请求头中的JWT令牌 Bearer access_token
        String token = authHeader.substring(7);
        String username = jwtTokenUtil.getUsernameFromToken(token);
        ArrayList<Permission> permissionList = basicService.findPermissionByUsername(username);
        return CommonResult.success(permissionList);
    }

    @ApiOperation("获取姓名的接口")
    @GetMapping("/get-name")
    public CommonResult<?> getName(@RequestHeader("Authorization") String authHeader) {
        // 解析Authorization请求头中的JWT令牌 Bearer access_token
        String token = authHeader.substring(7);
        String username = jwtTokenUtil.getUsernameFromToken(token);

        return CommonResult.success(basicService.getName(username));
    }


    @PostMapping("/password")
    public CommonResult<?> changePassword(@RequestHeader("Authorization") String authHeader, @RequestBody ChangePasswordReqVO body) {
        String token = authHeader.substring(7);
        String username = jwtTokenUtil.getUsernameFromToken(token);
        User user = basicService.findUserByUsername(username);

        if (user == null) {
            return CommonResult.error(50003, "用户不存在，修改密码失败");
        }

        if (!user.getPassword().equals(body.getOldPassword())) {
            return CommonResult.error(50003, "旧密码错误");
        }

        try {
            // 执行修改密码的操作
            basicService.changePassword(username, body.getNewPassword());
        } catch (Exception e) {
            // 处理修改失败的情况
            System.out.println(e.toString());
            return CommonResult.error(50003, "修改密码失败");
        }
        return CommonResult.success("修改密码成功");
    }

    @GetMapping("/acquire-major-information")
    public CommonResult<?> acquireMajor(@RequestHeader("Authorization") String authHeader) {
        return CommonResult.success(basicService.acquireMajor());
    }

    @GetMapping("/acquire-class-information")
    public CommonResult<?> acquireClass(@RequestHeader("Authorization") String authHeader) {
        return CommonResult.success(basicService.acquireClass());
    }

    @GetMapping("/acquire-mentor-information")
    public CommonResult<?> acquireMentor(@RequestHeader("Authorization") String authHeader) {
        return CommonResult.success(basicService.acquireMentor());
    }

    @GetMapping("/get-mentor-name")
    public CommonResult<?> getMentorNameByJobId(@RequestParam(name = "mentorId", defaultValue = "0") Integer mentorId) {
        try {
            MentorVO mentorVO = basicService.getMentorByMentorId(mentorId);
            return CommonResult.success(mentorVO);
        } catch (IllegalArgumentException e) {
            return CommonResult.error(50006, "导师工号错误！");
        }
    }

}